﻿//
// *************************************************************************************
// WP-Framework
// 
// Developed by
// Lukas Kretschmar (lkretschmar.dev@bluewin.ch)
//
// Switzerland, Copyright (c) 2013 lkretschmar
// This content is released under the MIT License (http://opensource.org/licenses/MIT).
//     
// *************************************************************************************
//
//
			

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Methods;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using KretschIT.WP_Fx.EasyMoq.Generator.Items;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Objects;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Constraints;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Events;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Properties;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Inheritance;

namespace KretschIT.WP_Fx.EasyMoq.Generator.Tests.Items
{
    [TestClass]
    public class TypeFinderTest
    {
        private ITypeFinder finder;

        [TestInitialize]
        public void Init()
        {
            this.finder = new TypeFinder();
        }

        [TestMethod]
        public void Test_GetGenericArgumentType()
        {
            var type = typeof(ITestSimpleGenericObject<Int32>);
            var types = this.finder.GetGenericTypeArgumentsOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericArgumentType_NotType()
        {
            var type = typeof(ITestSimpleGenericObject<>);
            var types = this.finder.GetGenericTypeArgumentsOf(type);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericArgumentType_OfNull()
        {
            var types = this.finder.GetGenericTypeArgumentsOf(null);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericArgumentType_OfNonGeneric()
        {
            var type = typeof(ITestObject);
            var types = this.finder.GetGenericTypeArgumentsOf(type);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericArgumentTypes()
        {
            var type = typeof(ITestComplexGenericObject<int, long, ITestObject>);
            var types = this.finder.GetGenericTypeArgumentsOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericArgumentTypes_NestedGenerics()
        {
            var type = typeof(ITestSimpleGenericObject<IEnumerable<IComparable<int>>>);
            var types = this.finder.GetGenericTypeArgumentsOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericArgumentTypes_NestedGenerics_ButDoublicates()
        {
            var type = typeof(ITestSimpleGenericObject<IEnumerable<IEnumerable<string>>>);
            var types = this.finder.GetGenericTypeArgumentsOf(type);
            Assert.AreEqual(2, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintType()
        {
            var type = typeof(ISimpleTypeConstraint<>);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintTypes()
        {
            var type = typeof(IMultiTypeConstraint<>);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(2, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintType_Dependend()
        {
            var type = typeof(IComplexGenericConstraint<,>);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintTypes_Dependend()
        {
            var type = typeof(IComplexGenericConstraint<IEnumerable<string>, string>);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintTypes_NestedConstraint()
        {
            var type = typeof(IVeryComplexGenericConstraint<,,>);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintTypes_OfNull()
        {
            var types = this.finder.GetGenericConstraintTypesOf(null);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintTypes_OfNonGeneric()
        {
            var type = typeof(ITestObject);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetGenericConstraintTypes_IgnoreValueType()
        {
            var type = typeof(IValueTypeConstraint<int>);
            var types = this.finder.GetGenericConstraintTypesOf(type);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetEventType()
        {
            var type = typeof(ITestSimpleEvent);
            var types = this.finder.GetEventTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetEventTypes_CustomArgument()
        {
            var type = typeof(ITestSimpleCustomArgument);
            var types = this.finder.GetEventTypesOf(type);
            Assert.AreEqual(2, types.Count());
        }

        [TestMethod]
        public void Test_GetEventTypes_OwnCustomArgument()
        {
            var type = typeof(ITestComplexCustomEvent);
            var types = this.finder.GetEventTypesOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetEventTypes_OfNull()
        {
            var types = this.finder.GetEventTypesOf(null);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetEventTypes_ComplexType()
        {
            var type = typeof(ITestAllEvent);
            var types = this.finder.GetEventTypesOf(type);
            Assert.AreEqual(5, types.Count());
        }

        [TestMethod]
        public void Test_GetEventTypes_Inheritance()
        {
            var type = typeof (ITop);
            var types = this.finder.GetEventTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes()
        {
            var type = typeof(ITestSimpleProperties);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_OfGenericDefinition()
        {
            var type = typeof(ITestGenericProperty<>);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_OfGenericType()
        {
            var type = typeof(ITestGenericProperty<int>);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(2, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_OfNull()
        {
            var types = this.finder.GetPropertyTypesOf(null);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_ComplexGenericDefinition()
        {
            var type = typeof(ITestComplexGenericProperty<>);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(2, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_CompleyGenericType()
        {
            var type = typeof(ITestComplexGenericProperty<bool>);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_SameTypesIgnored()
        {
            var type = typeof (ITestPropertyWithSameType);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetPropertyTypes_Inheritance()
        {
            var type = typeof (ITop);
            var types = this.finder.GetPropertyTypesOf(type);
            Assert.AreEqual(2, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodReturnType()
        {
            var type = typeof (ITestParameterLessMethod);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodReturnTypes_OfGeneric()
        {
            var type = typeof(ITestGenericReturnTypes<bool>);
            var types = this.finder.GetMethodTypesOf(type);

            Assert.AreEqual(1, types.Count());
            Assert.IsTrue(types.Contains(typeof(IEnumerable<>)));
        }

        [TestMethod]
        public void Test_GetMethodTypes_OfNull()
        {
            var types = this.finder.GetMethodTypesOf(null);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodTypes_Arguments()
        {
            var type = typeof(ITestParameterMethod);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(3, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodTypes_Arguments_IgnoreGenerics()
        {
            var type = typeof(ITestGenericMethodParameter);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(1, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodTypes_Constraints()
        {
            var type = typeof(ITestGenericMethodConstraint);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(4, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodTypes_IgnoreGenericReturnTypes()
        {
            var type = typeof(ITestGenericMethodReturn);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodTypes_IgnoreEvents()
        {
            var type = typeof(ITestAllEvent);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(0, types.Count());
        }

        [TestMethod]
        public void Test_GetMethodTypes_Inheritance()
        {
            var type = typeof (ITop);
            var types = this.finder.GetMethodTypesOf(type);
            Assert.AreEqual(2, types.Count());
        }
    }
}
